package org.grayrabbit.cms.util;

import java.io.StringReader;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.html.dom.HTMLDocumentImpl;
import org.cyberneko.html.parsers.DOMFragmentParser;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.html.HTMLDocument;
import org.xml.sax.InputSource;

public class HtmlTextConverter {
		
    public static String getPureTextFromHtml(String content){
    	
    	String key = getPureText(content);
    	key = key.replaceAll("<\\s*br\\s*/\\s*>", ""); 
    	key = key.replaceAll("\\s{2,}", "");
    	key = key.replaceAll(",{2,}",",");
    	if(key.startsWith(",")){
    		key = key.substring(1);
    	}
    	if(key.equals(",")){
    		key = null;
    	}
    	return  key;
    }
    
	public static String getPureText(String html) {
		DOMFragmentParser parser = new DOMFragmentParser();
		HTMLDocument document = new HTMLDocumentImpl();
		DocumentFragment fragment = document.createDocumentFragment();
		try {
			parser.parse(new InputSource(new StringReader(html)), fragment);
			String txt = getPureText(fragment);
			return HtmlTextConverter.htmlDecode(txt);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	
	
	public static String getPureText(Node node) {
		if ((!(node.hasChildNodes())) && (isTextNode(node))) {
			return node.getNodeValue();
		}
		if (isFiltered(node)) {
			return "";
		}
		if (node.hasAttributes()) {
			Node a = node.getAttributes().getNamedItem("style");
			if (a != null) {
				String style = a.getNodeValue();
				Pattern p = Pattern.compile("display\\s*\\:\\s*none", 2);
				if (p.matcher(style).find())
					return "";
			}
		}
		StringBuffer sb = new StringBuffer();
		NodeList list = node.getChildNodes();
		for (int i = 0; i < list.getLength(); ++i) {
			Node child = list.item(i);
			String name = child.getNodeName();
			sb.append(getPureText(child));
			sb.append(" ");
			if ((name.equalsIgnoreCase("TR")) || (name.equalsIgnoreCase("P"))
					|| (name.equalsIgnoreCase("DIV")))
				sb.append("\n");
		}

		return sb.toString();
	}
	
	private static boolean isFiltered(Node node) {
		short type = node.getNodeType();
		String name = node.getNodeName();
		if (type == Node.COMMENT_NODE)
			return true;

		if (name.equalsIgnoreCase("SCRIPT"))
			return true;

		if (name.equalsIgnoreCase("LINK"))
			return true;

		if (name.equalsIgnoreCase("STYLE")) {
			return true;
		}

		return (name.equalsIgnoreCase("OBJECT"));
	}
	public static boolean isTextNode(Node node) {
		if (node == null)
			return false;
		short nodeType = node.getNodeType();
		return ((nodeType == Node.CDATA_SECTION_NODE) || (nodeType == Node.TEXT_NODE));
	}
	
	public static String htmlDecode(String txt) {
	    txt = replaceEx(txt, "&#8226;", "·");
	    return StringEscapeUtils.unescapeHtml(txt);
	 }
	
	public static String replaceEx(String str, String subStr, String reStr)
	  {
	    if (str == null)
	      return null;

	    if ((subStr == null) || (subStr.equals("")) || (subStr.length() > str.length()) || (reStr == null))
	      return str;

	    StringBuffer sb = new StringBuffer();
	    String tmp = str;
	    int index = -1;
	    while (true) {
	      index = tmp.indexOf(subStr);
	      if (index < 0)
	        break;

	      sb.append(tmp.substring(0, index));
	      sb.append(reStr);
	      tmp = tmp.substring(index + subStr.length());
	    }

	    sb.append(tmp);
	    return sb.toString();
	  }
 
}
